package com.wangsh.userscenter.common.util;

import java.security.MessageDigest;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.RandomStringUtils;

/**
 * 各种加密工具 md5 sha256
 * 
 * @author zjx
 *
 */
public class EncryptUtil
{
	/**
	 * md5加密
	 * 
	 * @param s
	 * @return
	 */
	public final static String MD5(String s)
	{
		char hexDigits[] =
		{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D',
				'E', 'F' };
		try
		{
			byte[] btInput = s.getBytes();
			MessageDigest mdInst = MessageDigest.getInstance("MD5");
			mdInst.update(btInput);
			byte[] md = mdInst.digest();
			int j = md.length;
			char str[] = new char[j * 2];
			int k = 0;
			for (int i = 0; i < j; i++)
			{
				byte byte0 = md[i];
				str[k++] = hexDigits[byte0 >>> 4 & 0xf];
				str[k++] = hexDigits[byte0 & 0xf];
			}
			return new String(str);
		} catch (Exception e)
		{
			// e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * 对字符串进行加密
	 */
	public static String encode(final String password)
	{
		String salt = RandomStringUtils.random(32, true, true);
		String pwd = DigestUtils.sha256Hex(salt + password);
		String dbpwd = "sha256$" + salt + "$" + pwd;
		return dbpwd;
	}

	/**
	 * 验证密码是否一致
	 * 
	 * @param password
	 *            用户输入密码
	 * @param encryptPassword
	 *            数据库密码
	 * @return
	 * @throws Exception
	 */
	public static boolean checkPassword(String password, String encryptPassword)
	{
		if (password != null && !"".equalsIgnoreCase(password))
		{
			String[] ens = encryptPassword.split("\\$");
			if (ens.length == 3)
			{
				String salt = ens[1];
				String pwd = DigestUtils.sha256Hex(salt + password);
				String dbpwd = "sha256$" + salt + "$" + pwd;

				if (dbpwd.equals(encryptPassword))
				{
					return true;
				}
			}
		} else
		{
			return false;
		}
		return false;
	}

	private static String bytArrayToHex(byte[] a)
	{
		StringBuilder sb = new StringBuilder();
		for (byte b : a)
			sb.append(String.format("%02x", b & 0xff));
		return sb.toString();
	}

	/**
	 * 使用加密,与php的算法一致
	 * 
	 * @param data
	 * @param key
	 * @return
	 */
	public static String BtcChinaHmacSHA1(String data, String key)
	{
		String result = "";

		try
		{
			// get an hmac_sha1 key from the raw key bytes
			SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(),
					"HmacSHA1");

			// get an hmac_sha1 Mac instance and initialize with the signing key
			Mac mac = Mac.getInstance("HmacSHA1");
			mac.init(signingKey);

			// compute the hmac on input data bytes
			byte[] rawHmac = mac.doFinal(data.getBytes());

			result = bytArrayToHex(rawHmac);
		} catch (Exception e)
		{
			ConstatFinalUtil.SYS_LOG.error("加密算法失败," + data + "-->" + key, e);
		}
		return result;
	}

	/**
	 * 使用加密,与php的算法一致
	 * 
	 * @param data
	 * @param key
	 * @return
	 */
	public static String hmacSHA512(String data, String key)
	{
		String result = "";
		byte[] bytesKey = key.getBytes();
		final SecretKeySpec secretKey = new SecretKeySpec(bytesKey,
				"HmacSHA512");
		try
		{
			Mac mac = Mac.getInstance("HmacSHA512");
			mac.init(secretKey);
			final byte[] macData = mac.doFinal(data.getBytes());
			byte[] hex = new Hex().encode(macData);
			result = new String(hex, "ISO-8859-1");
		} catch (Exception e)
		{
			ConstatFinalUtil.SYS_LOG.error("加密算法失败," + data + "-->" + key, e);
		}
		return result;
	}

	/**
	 * 使用加密,与php的算法一致
	 * 
	 * @param data
	 * @param key
	 * @return
	 */
	public static String hmacSHA384(String data, String key)
	{
		String result = "";
		byte[] bytesKey = key.getBytes();
		final SecretKeySpec secretKey = new SecretKeySpec(bytesKey,
				"HmacSHA384");
		try
		{
			Mac mac = Mac.getInstance("HmacSHA384");
			mac.init(secretKey);
			final byte[] macData = mac.doFinal(data.getBytes());
			byte[] hex = new Hex().encode(macData);
			result = new String(hex, "ISO-8859-1");
		} catch (Exception e)
		{
			ConstatFinalUtil.SYS_LOG.error("加密算法失败," + data + "-->" + key, e);
		}
		return result;
	}

	/**
	 * 使用加密,与php的算法一致
	 * 
	 * @param data
	 * @param key
	 * @return
	 */
	public static String hmacSHA256(String data, String key)
	{
		String result = "";

		try
		{
			byte[] bytesKey = key.getBytes("UTF-8");
			final SecretKeySpec secretKey = new SecretKeySpec(bytesKey,
					"HmacSHA256");
			Mac mac = Mac.getInstance("HmacSHA256");
			mac.init(secretKey);
			result = Hex.encodeHexString(mac.doFinal(data.getBytes("UTF-8")));
		} catch (Exception e)
		{
			ConstatFinalUtil.SYS_LOG.error("加密算法失败," + data + "-->" + key, e);
		}
		return result;
	}

	/**
	 * 使用加密,与php的算法一致
	 * 
	 * @param data
	 * @param key
	 * @return
	 */
	public static String hmacSHA1(String data, String key)
	{
		String result = "";
		byte[] bytesKey = key.getBytes();
		final SecretKeySpec secretKey = new SecretKeySpec(bytesKey, "HmacSHA1");
		try
		{
			Mac mac = Mac.getInstance("HmacSHA1");
			mac.init(secretKey);
			final byte[] macData = mac.doFinal(data.getBytes());
			byte[] hex = new Hex().encode(macData);
			result = new String(hex, "ISO-8859-1");
		} catch (Exception e)
		{
			ConstatFinalUtil.SYS_LOG.error("加密算法失败," + data + "-->" + key, e);
		}
		return result;
	}
	
	public static void main(String[] args)
	{
		String res = EncryptUtil.MD5("111111");
		System.out.println(res);
	}
}
